package estore2;

import estore.model.Product;
import estore.model.User;
import estore.service.ProductService;
import estore.service.ProductSorters;
import estore.service.UserService;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class EStoreServer {
    private static final int PORT = 8888;
    private final ProductService productService = new ProductService();
    private final UserService userService = new UserService();

    public static void main(String[] args) {
        new EStoreServer().startServer();
    }

    private void startServer() {
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            System.out.println("服务器启动，监听端口：" + PORT);
            while (true) {
                Socket clientSocket = serverSocket.accept();
                System.out.println("客户端连接：" + clientSocket.getInetAddress());
                new Thread(() -> handleClient(clientSocket)).start();
            }
        } catch (IOException e) {
            System.err.println("服务器启动失败：" + e.getMessage());
        }
    }

    private void handleClient(Socket clientSocket) {
        try (ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream());
             ObjectOutputStream oos = new ObjectOutputStream(clientSocket.getOutputStream())) {
            User user = handleLogin(ois, oos);
            if (user == null) return;
            while (true) {
                Object requestObj = ois.readObject();
                if (requestObj instanceof String request) {
                    switch (request) {
                        case "GET_ALL_PRODUCTS":
                            handleGetAllProducts(oos);
                            break;
                        case "LOGOUT":
                            oos.writeObject("SUCCESS: 已退出登录");
                            return;
                        default:
                            oos.writeObject("未知请求");
                    }
                } else if (requestObj instanceof Map<?, ?> requestMap) {
                    String action = (String) requestMap.get("action");
                    switch (action) {
                        case "ADD_TO_CART":
                            handleAddToCart(requestMap, oos);
                            break;
                        case "UPDATE_STOCK":
                            if (user.isAdmin()) {
                                handleUpdateStock(requestMap, oos);
                            } else {
                                oos.writeObject("ERROR: 权限不足");
                            }
                            break;
                        case "ADD_PRODUCT":
                            if (user.isAdmin()) {
                                handleAddProduct(requestMap, oos);
                            } else {
                                oos.writeObject("ERROR: 权限不足");
                            }
                            break;
                        case "SORT_PRODUCTS":
                            handleSortedProducts(requestMap, oos);
                            break;
                        default:
                            oos.writeObject("未知操作");
                    }
                }
            }
        } catch (Exception e) {
            System.err.println("客户端处理失败：" + e.getMessage());
        } finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private User handleLogin(ObjectInputStream ois, ObjectOutputStream oos) throws Exception {
        Map<?, ?> loginMap = (Map<?, ?>) ois.readObject();
        String username = (String) loginMap.get("username");
        String password = (String) loginMap.get("password");
        User user = userService.login(username, password);
        if (user != null) {
            oos.writeObject("SUCCESS:" + user.getRole());
            return user;
        } else {
            oos.writeObject("ERROR: 用户名或密码错误");
            return null;
        }
    }

    private void handleGetAllProducts(ObjectOutputStream oos) throws IOException {
        oos.writeObject(productService.getAllProducts());
    }

    private void handleAddToCart(Map<?, ?> requestMap, ObjectOutputStream oos) throws IOException {
        String productId = (String) requestMap.get("productId");
        int quantity = (int) requestMap.get("quantity");
        Product product = productService.findProductById(productId);
        if (product == null) {
            oos.writeObject("ERROR: 商品不存在");
            return;
        }
        if (product.getStock() < quantity) {
            oos.writeObject("ERROR: 库存不足（当前：" + product.getStock() + "）");
            return;
        }
        product.setStock(product.getStock() - quantity);
        productService.saveData();
        oos.writeObject("SUCCESS: 添加成功");
    }

    private void handleUpdateStock(Map<?, ?> requestMap, ObjectOutputStream oos) throws IOException {
        String productId = (String) requestMap.get("productId");
        int newStock = (int) requestMap.get("newStock");
        Product product = productService.findProductById(productId);
        if (product == null) {
            oos.writeObject("ERROR: 商品不存在");
            return;
        }
        product.setStock(newStock);
        productService.saveData();
        oos.writeObject("SUCCESS: 库存更新为 " + newStock);
    }

    private void handleAddProduct(Map<?, ?> requestMap, ObjectOutputStream oos) throws IOException {
        String id = (String) requestMap.get("id");
        String name = (String) requestMap.get("name");
        double price = (double) requestMap.get("price");
        int stock = (int) requestMap.get("stock");
        productService.addProduct(new Product(id, name, price, stock));
        productService.saveData();
        oos.writeObject("SUCCESS: 商品添加成功");
    }

    private void handleSortedProducts(Map<?, ?> requestMap, ObjectOutputStream oos) throws IOException {
        int sortType = (int) requestMap.get("sortType");
        List<Product> products = productService.getAllProducts();
        switch (sortType) {
            case 1:
                products.sort(ProductSorters.BY_PRICE_ASC);
                break;
            case 2:
                products.sort(ProductSorters.BY_PRICE_DESC);
                break;
            case 3:
                products.sort(ProductSorters.BY_STOCK_DESC);
                break;
            default:
                products.sort(ProductSorters.BY_PRICE_ASC);
        }
        oos.writeObject(products);
    }
}